#include "fibevent.h"

#include "IocpOperation.h"
#include "IocpIoBaseInitiator.h"
#include "IocpFiber.h"

IocpIoBaseInitiator::IocpIoBaseInitiator(void)
	
{
}


IocpIoBaseInitiator::~IocpIoBaseInitiator(void)
{
}

void IocpIoBaseInitiator::TransmitFile(wxtl::File* file, size_t bytesToWrite, Buffer* head, Buffer* tail)
{
	IocpOperation* overlapped = new IocpOperation(IocpOperation::Io, &IocpFiber::Current());
	m_request = IocpIoRequest(overlapped, file, bytesToWrite, head, tail);

	Switch();
}

size_t IocpIoBaseInitiator::Read( void* data, size_t size )
{
	IocpOperation* overlapped = new IocpOperation(IocpOperation::Io, &IocpFiber::Current());
	m_request = IocpIoRequest(overlapped, IocpIoRequest::Read, data, size);
	
	Switch();

	return m_result.bytes;
}

size_t IocpIoBaseInitiator::Write( void* data, size_t size )
{
	IocpOperation* overlapped = new IocpOperation(IocpOperation::Io, &IocpFiber::Current());
	m_request = IocpIoRequest(overlapped, IocpIoRequest::Write, data, size);
		
	Switch();

	return m_result.bytes;
}

void IocpIoBaseInitiator::OnSwithcedContext()
{
	//reset last iocp request data
	m_request.m_type = IocpIoRequest::None;

	BaseIocpInitiator::OnSwithcedContext();
}

bool IocpIoBaseInitiator::IocpCopy( IocpIoBaseInitiator* to, size_t length , size_t portion /*= 16192*/ )
{
	IocpIoBaseInitiator* from = this;
	char* buffer = (char*)alloca(portion);
	size_t left = length;
	while(left)
	{
		const size_t toRead = min(portion, left);
		size_t bytes = from->Read(buffer, toRead);
		if(!bytes)
		{
			return false;
		}

		size_t sended = to->Write(buffer, bytes);
		if(sended != bytes)
		{
			return false;
		}

		left -= bytes;
	}

	return true;
}


